package com.ruoyi.web.controller.modules;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.oss.service.AliyunOssService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageableEntitiesConverter;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.web.domain.knowledgebase.KnowledgeBase;
import com.ruoyi.web.pojo.dto.Knowledge.CropKnowledgeBase;
import com.ruoyi.web.pojo.dto.Knowledge.DiseaseKnowledgeBase;
import com.ruoyi.web.pojo.dto.Knowledge.KnowledgeBaseBo;
import com.ruoyi.web.pojo.dto.Knowledge.PestKnowledgeBase;
import com.ruoyi.web.service.knowledgebase.KnowledgeBaseService;
import com.sun.istack.NotNull;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassName: KnowledgeBaseController
 * @author: z越
 * @date: 2024/2/18  15:59
 * @description
 */
@RestController
@RequestMapping("/knowledge/base")
@Api(tags = "知识库管理")
public class KnowledgeBaseController extends BaseController {

    private final AliyunOssService aliyunOssService;
    private final KnowledgeBaseService knowledgeBaseService;

    public KnowledgeBaseController(AliyunOssService aliyunOssService, KnowledgeBaseService knowledgeBaseService) {
        this.aliyunOssService = aliyunOssService;
        this.knowledgeBaseService = knowledgeBaseService;
    }

    @GetMapping
    @ApiOperation("列表查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名称查询", defaultValue = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "type", value = "查询类型（pest:虫害，crop：植物，disease：病害）", defaultValue = "String", dataTypeClass = String.class)
    })
    public TableDataInfo<KnowledgeBaseBo> list(@RequestParam(required = false) String name, @RequestParam String type,int pageSize,int pageNum) {
        LambdaQueryWrapper<KnowledgeBase> wrapper = new LambdaQueryWrapper<KnowledgeBase>()
                .eq(KnowledgeBase::getType, type);
        if (StringUtils.isNotEmpty(name)) {
            wrapper.like(KnowledgeBase::getName, name);
        }
        startPage();
        wrapper.orderByDesc(KnowledgeBase::getCreateTime);
        List<KnowledgeBase> list = this.knowledgeBaseService.list(wrapper);
        List<KnowledgeBaseBo> baseBos = PageableEntitiesConverter.toVos(list, this::toPo);
        return getDataTable(baseBos);
    }

    private List<KnowledgeBaseBo> toPo(List<KnowledgeBase> list) {
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(KnowledgeBaseBo::new).collect(Collectors.toList());
    }

    @GetMapping("/{id}")
    @ApiOperation("查询详情")
    public AjaxResult getInfo(@PathVariable @NotNull Long id ){
        KnowledgeBase entity = this.knowledgeBaseService.getById(id);
        if (Objects.isNull(entity)) throw new IllegalArgumentException("未查询到当前id的数据，请核对后重新操作！");
        KnowledgeBaseBo baseBo = new KnowledgeBaseBo(entity);
        return AjaxResult.success(baseBo);
    }

    @PostMapping("/pest/import")
    @ApiOperation("虫害知识库导入")
    @RateLimiter
    public AjaxResult pestImport(MultipartFile file) throws IOException {
        String filePath = this.createFilePath(file);
        ExcelUtil<PestKnowledgeBase> util = new ExcelUtil<>(PestKnowledgeBase.class, filePath, null, this.aliyunOssService);
        List<PestKnowledgeBase> result = util.importExcel(file.getInputStream());
        if (CollectionUtil.isEmpty(result)) {
            return AjaxResult.error("导入失败，模板文件为空！");
        }
        StringBuilder message = new StringBuilder();
        List<KnowledgeBase> pest = this.knowledgeBaseService.findAllByType("pest");
        if (CollectionUtil.isNotEmpty(pest)) {
            int i = 2;
            Map<String, KnowledgeBase> baseMap = pest.stream().collect(Collectors.toMap(KnowledgeBase::getName, Function.identity()));
            for (PestKnowledgeBase po : result) {
                if (Objects.nonNull(baseMap.get(po.getPestName()))){
                    message.append(i).append(",");
                }
                i++;
            }
        }
        List<KnowledgeBase> pos = result.stream().map(PestKnowledgeBase::toPo).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(message.toString())) {
            message = new StringBuilder("第" + message + "行虫害已存在，请核对后重新导入");
            return AjaxResult.error(message.toString());
        }
        return AjaxResult.success(this.knowledgeBaseService.saveBatch(pos));
    }

    @PostMapping("/pest/export")
    @ApiOperation("下载虫害知识库导入模板")
    @RateLimiter
    public void exportPestTemplate(HttpServletResponse response) {
        ExcelUtil<PestKnowledgeBase> util = new ExcelUtil<>(PestKnowledgeBase.class);
        util.exportExcel(response, new ArrayList<PestKnowledgeBase>(), "虫害知识库");
    }

    @PostMapping("/pest/edit")
    @ApiOperation("新增或修改虫害知识库数据")
    @RateLimiter
    public AjaxResult editPest(@RequestBody @Validated PestKnowledgeBase entity) {
        KnowledgeBase poName = this.knowledgeBaseService.findByName(entity.getPestName());
        KnowledgeBase po = entity.toPo();
        if (null == entity.getId()) {
            if (Objects.nonNull(poName)) {
                return AjaxResult.error("虫害已存在，请核对后重新提交");
            }
            return AjaxResult.success(this.knowledgeBaseService.save(po));
        }
        if (Objects.nonNull(poName) && !entity.getId().equals(poName.getId())) {
            return AjaxResult.error("虫害已存在，请核对后重新提交");
        }
        KnowledgeBase base = this.knowledgeBaseService.getById(entity.getId());
        if (Objects.isNull(base)) {
            return AjaxResult.error("未查询到此id数据，请核对后重新提交");
        }
        po.setId(entity.getId());
        return AjaxResult.success(this.knowledgeBaseService.updateById(po));
    }

    @PostMapping("/disease/import")
    @ApiOperation("病害知识库导入")
    @RateLimiter
    public AjaxResult diseaseImport(MultipartFile file) throws IOException {
        String filePath = this.createFilePath(file);
        ExcelUtil<DiseaseKnowledgeBase> util = new ExcelUtil<>(DiseaseKnowledgeBase.class, filePath, null, this.aliyunOssService);
        List<DiseaseKnowledgeBase> result = util.importExcel(file.getInputStream());
        if (CollectionUtil.isEmpty(result)) {
            return AjaxResult.error("导入失败，模板文件为空！");
        }
        StringBuilder message = new StringBuilder();
        List<KnowledgeBase> pest = this.knowledgeBaseService.findAllByType("disease");
        if (CollectionUtil.isNotEmpty(pest)) {
            int i = 2;
            Map<String, KnowledgeBase> baseMap = pest.stream().collect(Collectors.toMap(KnowledgeBase::getName, Function.identity()));
            for (DiseaseKnowledgeBase po : result) {
                if (Objects.nonNull(baseMap.get(po.getDiseaseName()))){
                    message.append(i).append(",");
                }
                i++;
            }
        }
        List<KnowledgeBase> pos = result.stream().map(DiseaseKnowledgeBase::toPo).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(message.toString())) {
            message = new StringBuilder("第" + message + "行病害已存在，请核对后重新导入");
            return AjaxResult.error(message.toString());
        }
        return AjaxResult.success(this.knowledgeBaseService.saveBatch(pos));
    }

    @PostMapping("/disease/export")
    @ApiOperation("下载病害知识库导入模板")
    @RateLimiter
    public void exportDiseaseTemplate(HttpServletResponse response) {
        ExcelUtil<DiseaseKnowledgeBase> util = new ExcelUtil<>(DiseaseKnowledgeBase.class);
        util.exportExcel(response, new ArrayList<DiseaseKnowledgeBase>(), "病害知识库");
    }

    @PostMapping("/disease/edit")
    @ApiOperation("新增或修改病害知识库数据")
    @RateLimiter
    public AjaxResult editDisease(@RequestBody @Validated DiseaseKnowledgeBase entity) {
        KnowledgeBase poName = this.knowledgeBaseService.findByName(entity.getDiseaseName());
        KnowledgeBase po = entity.toPo();
        if (null == entity.getId()) {
            if (Objects.nonNull(poName)) {
                return AjaxResult.error("病害已存在，请核对后重新提交");
            }
            return AjaxResult.success(this.knowledgeBaseService.save(po));
        }
        if (Objects.nonNull(poName) && !entity.getId().equals(poName.getId())) {
            return AjaxResult.error("病害已存在，请核对后重新提交");
        }
        KnowledgeBase base = this.knowledgeBaseService.getById(entity.getId());
        if (Objects.isNull(base)) {
            return AjaxResult.error("未查询到此id数据，请核对后重新提交");
        }
        po.setId(entity.getId());
        return AjaxResult.success(this.knowledgeBaseService.updateById(po));
    }

    @PostMapping("/crop/import")
    @ApiOperation("植物知识库导入")
    @RateLimiter
    public AjaxResult cropImport(MultipartFile file) throws IOException {
        String filePath = this.createFilePath(file);
        ExcelUtil<CropKnowledgeBase> util = new ExcelUtil<>(CropKnowledgeBase.class, filePath, null, this.aliyunOssService);
        List<CropKnowledgeBase> result = util.importExcel(file.getInputStream());
        if (CollectionUtil.isEmpty(result)) {
            return AjaxResult.error("导入失败，模板文件为空！");
        }
        StringBuilder message = new StringBuilder();
        List<KnowledgeBase> pest = this.knowledgeBaseService.findAllByType("crop");
        if (CollectionUtil.isNotEmpty(pest)) {
            int i = 2;
            Map<String, KnowledgeBase> baseMap = pest.stream().collect(Collectors.toMap(KnowledgeBase::getName, Function.identity()));
            for (CropKnowledgeBase po : result) {
                if (Objects.nonNull(baseMap.get(po.getCropName()))){
                    message.append(i).append(",");
                }
                i++;
            }
        }
        List<KnowledgeBase> pos = result.stream().map(CropKnowledgeBase::toPo).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(message.toString())) {
            message = new StringBuilder("第" + message + "行植物已存在，请核对后重新导入");
            return AjaxResult.error(message.toString());
        }
        return AjaxResult.success(this.knowledgeBaseService.saveBatch(pos));
    }

    @PostMapping("/crop/export")
    @ApiOperation("下载植物知识库导入模板")
    @RateLimiter
    public void exportCropTemplate(HttpServletResponse response) {
        ExcelUtil<CropKnowledgeBase> util = new ExcelUtil<>(CropKnowledgeBase.class);
        util.exportExcel(response, new ArrayList<CropKnowledgeBase>(), "植物知识库");
    }

    @PostMapping("/crop/edit")
    @ApiOperation("新增或修改植物知识库数据")
    @RateLimiter
    public AjaxResult editCrop(@RequestBody @Validated CropKnowledgeBase entity) {
        KnowledgeBase poName = this.knowledgeBaseService.findByName(entity.getCropName());
        KnowledgeBase po = entity.toPo();
        if (null == entity.getId()) {
            if (Objects.nonNull(poName)) {
                return AjaxResult.error("植物已存在，请核对后重新提交");
            }
            return AjaxResult.success(this.knowledgeBaseService.save(po));
        }
        if (Objects.nonNull(poName) && !entity.getId().equals(poName.getId())) {
            return AjaxResult.error("植物已存在，请核对后重新提交");
        }
        KnowledgeBase base = this.knowledgeBaseService.getById(entity.getId());
        if (Objects.isNull(base)) {
            return AjaxResult.error("未查询到此id数据，请核对后重新提交");
        }
        po.setId(entity.getId());
        return AjaxResult.success(this.knowledgeBaseService.updateById(po));
    }

    @DeleteMapping("/{id}")
    @ApiOperation("删除数据")
    @RateLimiter
    public AjaxResult delete(@PathVariable Long id) {
        if (null == id) {
            return AjaxResult.error("请核对数据后重新提交");
        }
        KnowledgeBase po = this.knowledgeBaseService.getById(id);
        if (Objects.isNull(po)) {
            return AjaxResult.error("未查询到此id数据，请核对后重新提交");
        }
        return AjaxResult.success(this.knowledgeBaseService.removeById(id));
    }

    private String createFilePath(MultipartFile file) {
        String filePath =  RuoYiConfig.getImportPath() + file.getOriginalFilename();
//        String filePath = "E:/data\\beyond/" + StringUtils.format("{}/{}", DateUtils.datePath(),
//                file.getOriginalFilename());
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write(file.getBytes());
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }

}
